package com.zkhz.base.security.authentication.userdetails;

import com.alibaba.fastjson.JSON;
import com.zkhz.base.constant.enums.ErrorStatus;
import com.zkhz.base.domian.entity.MyUser;
import com.zkhz.base.exception.BusinessException;
import com.zkhz.base.mapper.MyUserMapper;
import com.zkhz.base.security.authentication.userdetails.facade.ExtractSecurityUserService;
import com.zkhz.base.security.authentication.userdetails.model.SecurityUserDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.Assert;

import java.util.Collections;
import java.util.Map;

/**
 * 登录用户提取逻辑服务类
 *
 * @author wuzeqin
 * @date 2020/5/28
 **/
public class TenantUserDetailsServiceImpl implements UserDetailsService, InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(TenantUserDetailsServiceImpl.class);

    private final MyUserMapper myUserMapper;

    private ExtractSecurityUserService extractSecurityUserService;

    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public TenantUserDetailsServiceImpl(MyUserMapper myUserMapper, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.myUserMapper = myUserMapper;
        this.extractSecurityUserService = defaultExtractSecurityUserService();
    }

    public void setExtractSecurityUserService(ExtractSecurityUserService extractSecurityUserService) {
        this.extractSecurityUserService = extractSecurityUserService;
    }

    @Override
    public UserDetails loadUserByUsername(String loginName) {
        LOGGER.debug("loading User: {}", loginName);
        MyUser user = myUserMapper.findByUsername(loginName);
        if (user == null || Boolean.TRUE.equals(user.getDeleted())) {
            LOGGER.debug("loginName: {} not found!", loginName);
            throw new BusinessException(ErrorStatus.A0201, ErrorStatus.A0201.getDetail());
        }

        Map<String, String> userInfo = extractSecurityUserService.extractUserInfo(user);
        userInfo.remove("password");
        userInfo.remove("schrodingerCat");

        return new SecurityUserDetails(loginName, user.getPassword(), true, true, true, Collections.emptySet(), userInfo);

    }

    private ExtractSecurityUserService defaultExtractSecurityUserService() {
        return user -> (Map<String, String>) JSON.toJSON(user);
    }

    @Override
    public void afterPropertiesSet() {
        Assert.notNull(myUserMapper, "myUserMapper is null");
        Assert.notNull(extractSecurityUserService, "extractSecurityUserService is null");
    }

}
